//
//  Stock_VC.m
//  KaChing_App
//
//  Created by Jordan Robert Yust on 4/8/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "Stock_VC.h"
#import "Constants.h"
#import "AsyncImageView.h"

@implementation Stock_VC

@synthesize dataManager;
@synthesize numberFormatter;
@synthesize trade_VC;

@synthesize stockPrice_number;
@synthesize priceChange_number;
@synthesize add2Watchlist_AlertView;

@synthesize tickerSearchBar;
@synthesize stockName_Label;
@synthesize price_Label;
@synthesize dailyChange_Label;
@synthesize wallTableView;
@synthesize tradeButton;
@synthesize watchlistButton;
@synthesize timeStampInputFormatter;
@synthesize timeStampOutputFormatter;
@synthesize stockWall;

/*
 // Override initWithNibName:bundle: to load the view using a nib file then perform additional customization that is not appropriate for viewDidLoad.
 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
 if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
 // Custom initialization
 }
 return self;
 }
 */

/*
 // Implement loadView to create a view hierarchy programmatically.
 - (void)loadView {
 }
 */

// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad
{
	[self createFormatters];	// Creates the formatters
	
	[super viewDidLoad];
	
	//set the search bar preferences
	tickerSearchBar.autocorrectionType = UITextAutocorrectionTypeNo;
}

/*
 ------------------------------------------------------------------------
 UISearchBarDelegate Protocol methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark UISearchBarDelegate Protocol methods

/*
 
 This method is called whenever the search button in the search bar is clicked.
 NOTE: This is one of the methods in the search bar delegate protocol.
 */
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
	/* If the search bar is the ticker search bar (should always be the case..) */
	if (searchBar == tickerSearchBar)
	{
		[searchBar resignFirstResponder];	// Hides the text pad
		
		/* KaChing API call.  This retrieves the security with the given symbol (i.e., ticker) */
		NSDictionary *tickerDictionary = (NSDictionary *)[self.dataManager getSecurity:searchBar.text];
	
		/* KaChing API call.  This retrieves the wall corresponding to the security with the given symbol (i.e., ticker) */
		self.stockWall = [self.dataManager getWallForStock: searchBar.text];
		[wallTableView reloadData];
	
		/* No stock was returned that matched the ticker provided */
		if ([tickerDictionary count] == 0)
		{
			/* Displays an AlertView showing insufficient criteria */
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Stock Found" message:@"Please enter a valid stock ticker"
														   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
			[alert show];
			[alert release];
			
			/* If text was shown in the label, get rid of it */
			stockName_Label.text = @"???";
			price_Label.text = @"$0.00";
			dailyChange_Label.text = @"$0.00";
			
			/* Since no ticker is available to trade, disable the trade and watchlist buttons */
			[tradeButton setEnabled:FALSE];
			[watchlistButton setEnabled:FALSE];
			
		}
		/* A valid stock ticker was entered */
		else
		{
			/* Since ticker is available to trade, enable the trade and watchlist buttons */
			[tradeButton setEnabled:TRUE];
			[watchlistButton setEnabled:TRUE];
			
			for (NSString *key in [tickerDictionary allKeys])
			{
				stockName_Label.text = key;	// Update the stock name label with the current ticker
				NSDictionary *stockDictionary = (NSDictionary *) [tickerDictionary objectForKey:key];	// Get's the stock's dictionary
				
				/* Store the stock's price and daily change as NSNumbers */
				[self setStockPrice_number:[NSNumber numberWithFloat:[[stockDictionary valueForKey:@"lastRealTimePrice"] floatValue]]];
				[self setPriceChange_number:[NSNumber numberWithFloat:[[stockDictionary valueForKey:@"lastRealTimeChange"] floatValue]]];
				
				// Update the text of the price label
				price_Label.text = [@"$" stringByAppendingString:[numberFormatter stringFromNumber:stockPrice_number]];	
				
				/* If the daily change is negative */
				if ([priceChange_number floatValue] < 0)
				{
					/* Remove the negative sign ('-') from the number and update the label's text */
					dailyChange_Label.text = [@"$" stringByAppendingString:[[numberFormatter stringFromNumber:priceChange_number] substringFromIndex:2]];
					
					/* Change the text to red */
					dailyChange_Label.textColor = [UIColor redColor];
				}
				/* The daily change is zero (no change) */
				else if ([priceChange_number floatValue] == 0)
				{
					/* Update the label's text and change the color to black */
					dailyChange_Label.text = [@"$" stringByAppendingString:[numberFormatter stringFromNumber:priceChange_number]];
					dailyChange_Label.textColor = [UIColor blackColor];
				}
				/* The daily change is positive */
				else
				{
					/* Update the label's text and change the color to green */
					dailyChange_Label.text = [@"$" stringByAppendingString:[numberFormatter stringFromNumber:priceChange_number]];
					dailyChange_Label.textColor = [UIColor customGreen];
				}
			}
		}
	}
}

// called when cancel button pressed
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
	/* Hides the keyboard */
	[tickerSearchBar resignFirstResponder];
}

/*
 ------------------------------------------------------------------------
 UITableView Protocol methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark UITableView Protocol methods

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
	
	if(tableView == wallTableView)
		return 1;
	else 
		return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
	if(tableView == wallTableView)
	{
		NSLog(@"\n\n\n Number posts: %d", [(NSArray *)[stockWall objectForKey:@"posts"] count]);
		//get the number of wall posts
		return [[stockWall objectForKey:@"posts"] count];
	}
	else 
		return 1;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	static NSString *CellIdentifier = @"Cell";
	
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	
	if(tableView == wallTableView)
	{
		NSLog(@"Entered cellForRow@IndexPath");
		//get the htmlContent
		NSString *htmlContent = [[[stockWall objectForKey:@"posts"] objectAtIndex:indexPath.row] objectForKey:@"htmlContent"];
		
		//get the user that posted
		NSString *user = [[[[stockWall objectForKey:@"posts"] objectAtIndex:indexPath.row] objectForKey:@"author"] objectForKey:@"fullName"];
		
		//get the timeStamp
		NSString *timeStamp = [[[stockWall objectForKey:@"posts"] objectAtIndex:indexPath.row] objectForKey:@"timestamp"];
		
		//Run the timeStamp through the timeStampDateformatter
		NSDate *timeStampDate = [timeStampInputFormatter dateFromString:timeStamp];
		
		CGRect postViewFrame = CGRectZero;
		CGRect picFrame = CGRectZero;
		CGRect timeFrame = CGRectZero;
		if (cell == nil)
		{
			cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
			cell.selectionStyle = UITableViewCellSelectionStyleNone;	// Mark cell as unable to be selected
			
			//create the label for posts without hyperlinks in them
			UILabel *postView = [[UILabel alloc] initWithFrame:postViewFrame];
			[postView setFont:[UIFont fontWithName:@"Arial" size:14]];
			
			[cell.contentView addSubview:postView];
			
			//memory management
			[postView release];
			
			timeFrame.size.width = cell.contentView.frame.size.width - 30;  timeFrame.size.height = cell.contentView.frame.size.height - 30;
			
			//specify location of frame within cell
			timeFrame.origin.x=30; timeFrame.origin.y=0;
			
			//create the label for posts without hyperlinks in them
			UILabel *timeSenderLabel = [[UILabel alloc] initWithFrame:timeFrame];
			//set label attributes
			timeSenderLabel.textColor = [UIColor grayColor];
			timeSenderLabel.font = [UIFont fontWithName:@"Helvetica Neue" size:12];
			
			//[timeSenderLabel 
			[cell.contentView addSubview:timeSenderLabel];
			
			//memory management
			[timeSenderLabel release];
		}
		
		//get the number of lines for the post
		
		//get the length of the content
		NSInteger numLines = ([htmlContent length] / 43) - (([htmlContent length] % 43) / 43) + 2;
		
		//debug
		NSLog(htmlContent);
		//debug
		NSLog(@"Row: %d Author: %@ \n\tNumber of Characters: %d \n \tNumber of Lines: %d", indexPath.row, user, [htmlContent length], numLines);
		
		//set timeStamp equal to the newly formatted date
		timeStamp = [timeStampOutputFormatter stringFromDate:timeStampDate];
		
		//set the size of the HTML content label
		CGSize maxSize = CGSizeMake(300, 10000);
		CGRect tempFrame;
		tempFrame.size = [htmlContent sizeWithFont:[UIFont fontWithName:@"Arial" size:14] constrainedToSize:maxSize lineBreakMode:UILineBreakModeWordWrap];
		tempFrame.origin.x = 0; tempFrame.origin.y = 25;
		[[cell.contentView.subviews objectAtIndex:0] setFrame:tempFrame];
		
		//put the HTML content in the label
		[[cell.contentView.subviews objectAtIndex:0] setText:htmlContent];
		[(UILabel *)[cell.contentView.subviews objectAtIndex:0] setNumberOfLines:0];
		
		//add the sender and the time that it was sent to the timeSenderLabel
		[[cell.contentView.subviews objectAtIndex:1] setText:[NSString stringWithFormat:@"%@ wrote on %@", user, timeStamp]];
		
		/*Code to add in the new image to the cell*/
		//specify frame size
		picFrame.size.width=25; picFrame.size.height=25;
		
		//specify location of frame within cell
		picFrame.origin.x=0; picFrame.origin.y=0;
		
		//create a new asynchronous image object 
		AsyncImageView* asyncImage = [[[AsyncImageView alloc]
									   initWithFrame:picFrame] autorelease];
		
		//set the tag so that we know the image has been added
		asyncImage.tag = 999;
		
		//get the stock image url
		if([[[[stockWall objectForKey:@"posts"] objectAtIndex:indexPath.row] objectForKey:@"author"] objectForKey:@"picture"]!= NULL)
		{
			NSURL* url = [NSURL URLWithString:(NSString *) [[[[stockWall objectForKey:@"posts"] objectAtIndex:indexPath.row] objectForKey:@"author"] objectForKey:@"picture"]];
			
			[asyncImage loadImageFromURL:url];
			
			[cell.contentView addSubview:asyncImage];
		}
		else
		{
			NSURL* url = [NSURL URLWithString:@"http://www.kaching.com/default_user_image.gif"];
			
			[asyncImage loadImageFromURL:url];
			
			[cell.contentView addSubview:asyncImage];
		}
	}
	
	//Debug
	//NSLog(@"height: %d width: %d", [cell.contentView.subviews objectAtIndex:0].frame.size.width, [cell.contentView.subviews objectAtIndex:0].frame.size.height);
	return cell;
}

/*
 This method allows me to create a custom height for each tableViewCell, based on the content
 of each cell. So, I search through the htmlContent of the posts to determine if they are longer
 than the max number of characters on a line, and if they are I add the appropriate space to the
 tableViewRow
 */
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
	if(tableView == wallTableView)
	{
		//get the html string corresponding to this row
		NSString *htmlContent = [[[stockWall objectForKey:@"posts"] objectAtIndex:indexPath.row] objectForKey:@"htmlContent"];
		
		CGSize maxSize = CGSizeMake(300, 10000);
		return [htmlContent sizeWithFont:[UIFont fontWithName:@"Arial" size:14] constrainedToSize:maxSize lineBreakMode:UILineBreakModeWordWrap].height + 27;
	}
	else{
		return 40;
	}
	
}

/*
 This method specifies the Header of the current section in the tableView.
 NOTE: This method is part of the UITableViewDataSource Protocol.
 */
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
	if(tableView == wallTableView)
	{
		return @"Stock's Wall";
	}
	else
		return @"Error";
}

/*
 This method specifies the Header of the current section in the tableView.
 NOTE: This method is part of the UITableViewDataSource Protocol.
 */
//- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
//{
//	return @"Standings";
//}

/*
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
 }
 */

/*
 - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
 
 if (editingStyle == UITableViewCellEditingStyleDelete) {
 }
 if (editingStyle == UITableViewCellEditingStyleInsert) {
 }
 }
 */

/*
 - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
 return YES;
 }
 */

/*
 - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
 }
 */

/*
 - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
 return YES;
 }
 */


/*
 ------------------------------------------------------------------------
 IBAction Methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark IBAction Methods

- (IBAction) refreshStockPrice
{
	/* KaChing API call.  This retrieves the security that is currently in the label's text */
	NSDictionary *tickerDictionary = (NSDictionary *)[self.dataManager getSecurity:stockName_Label.text];
	
	for (NSString *key in [tickerDictionary allKeys])
	{
		stockName_Label.text = key;	// Update the stock name label with the current ticker
		NSDictionary *stockDictionary = (NSDictionary *) [tickerDictionary objectForKey:key];	// Get's the stock's dictionary
		
		/* Store the stock's price and daily change as NSNumbers */
		[self setStockPrice_number:[NSNumber numberWithFloat:[[stockDictionary valueForKey:@"lastRealTimePrice"] floatValue]]];
		[self setPriceChange_number:[NSNumber numberWithFloat:[[stockDictionary valueForKey:@"lastRealTimeChange"] floatValue]]];
		
		// Update the text of the price label
		price_Label.text = [@"$" stringByAppendingString:[numberFormatter stringFromNumber:stockPrice_number]];	
		
		/* If the daily change is negative */
		if ([priceChange_number floatValue] < 0)
		{
			/* Remove the negative sign ('-') from the number and update the label's text */
			dailyChange_Label.text = [@"$" stringByAppendingString:[[numberFormatter stringFromNumber:priceChange_number] substringFromIndex:2]];
			
			/* Change the text to red */
			dailyChange_Label.textColor = [UIColor redColor];
		}
		/* The daily change is zero (no change) */
		else if ([priceChange_number floatValue] == 0)
		{
			/* Update the label's text and change the color to black */
			dailyChange_Label.text = [@"$" stringByAppendingString:[numberFormatter stringFromNumber:priceChange_number]];
			dailyChange_Label.textColor = [UIColor blackColor];
		}
		/* The daily change is positive */
		else
		{
			/* Update the label's text and change the color to green */
			dailyChange_Label.text = [@"$" stringByAppendingString:[numberFormatter stringFromNumber:priceChange_number]];
			dailyChange_Label.textColor = [UIColor customGreen];
		}
	}
}

/* This method is called when the user clicks the button for trading the stock.  It navigates to the Trade
 View Controller, and passes along any necessary fields to the view controller. */
- (IBAction) tradeStock
{	
	/* If no stock is contained in the stock label */
	if ([stockName_Label.text length] == 0)
	{
		/* Displays an AlertView showing insufficient criteria */
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Empty stock ticker" message:@"Please specify a stock to trade"
													   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
		[alert show];
		[alert release];
	}
	else
	{
		/* Creates the new Trade_VC (and adheres to memory management) */
		Trade_VC *tempVC = [[Trade_VC alloc] initWithNibName:@"Trade_VC" bundle:[NSBundle mainBundle]];
		[self setTrade_VC:tempVC];
		[tempVC release];
		
		/* Passes along all necessary fields used by trade_VC */
		[trade_VC setDataManager:dataManager];	// DataManager field
		[trade_VC setStockTicker:stockName_Label.text];	// The stock ticker (as a string)
		
		/* Transitions to the Trade_VC */
		[self.navigationController pushViewController:trade_VC animated:YES];
		
		/* Updates the title of the view with the stock ticker */
		trade_VC.title = stockName_Label.text;
	}
	
}

/* Adds the ticker to the watch list */
- (IBAction) add_2_WatchList
{
	/* If no stock is contained in the stock label */
	if ([stockName_Label.text length] == 0)
	{
		/* Displays an AlertView showing insufficient criteria */
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Empty stock ticker" message:@"Please specify a stock to add to the Watch List"
													   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
		[alert show];
		[alert release];
	}
	/* A stock is contained in the stock label */
	else
	{
		/* Displays an AlertView verifying user wants to add stock to watch list */
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Please confirm" message:[NSString stringWithFormat:@"Are you sure you want to add %@ to your Watch List?", stockName_Label.text]
													   delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes", nil];
		[alert show];		
		[self setAdd2Watchlist_AlertView:alert];
		[alert  release];
		
	}
}

/*
 ------------------------------------------------------------------------
 UIAlertView Delegate Methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark UIAlertView Delegate Methods

/*
 This method is called whenever a button in an AlertView is clicked in the current view. 
 NOTE: This method is part  of the UIAlertViewDelegate protocol.
 The 'alertView' parameter is the actual AlertView object.
 The 'buttonIndex' parameter is the index number of the button that was pressed in the AlertView.
 */
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	/* If the alertView method parameter is equal to the add2Watchlist alert view */
	if (alertView == add2Watchlist_AlertView)
	{
		/* If the button index is the one signifying that the user wants to add the stock to the Watch List */
		if (buttonIndex == add2Watchlist_AlertViewIndex)
		{
			NSLog(@"He wants to add it!!  The text in the label is: %@", stockName_Label.text);
			
			/* KaChing API call: adds the stock to the watch list */
			[dataManager addToWatchList:stockName_Label.text];
		}
	}
}

/*
 ------------------------------------------------------------------------
 Private Methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark Private Methods

/* This method creates the necessar formatter objects used when displaying numbers/text in the view */
- (void) createFormatters
{
	/* NUMBER FORMATTER CREATION */
	numberFormatter = [[NSNumberFormatter alloc] init];
	[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
	[numberFormatter setPositiveFormat:@"###,##0.00;0.00; -##,##0.00"];
	[numberFormatter setNegativeFormat:@"###,##0.00;0.00; -##,##0.00"];
	NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
	[numberFormatter setLocale:usLocale];
	[usLocale release];
	
	//format the timeStamp
	timeStampInputFormatter = [[NSDateFormatter alloc] init];
	timeStampOutputFormatter = [[NSDateFormatter alloc] init];
	[timeStampInputFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm"];
	[timeStampOutputFormatter setDateFormat:@"MM/dd/yyyy 'at' HH:mm"];
}


#pragma mark -

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


- (void)dealloc 
{
	[dataManager release];
	[numberFormatter release];
	[trade_VC release];
	[stockPrice_number release];
	[priceChange_number release];
	[add2Watchlist_AlertView release];
	[tickerSearchBar release];
	[stockName_Label release];
	[price_Label release];
	[dailyChange_Label release];
	[wallTableView release];
    [tradeButton release];
	[watchlistButton release];
	[timeStampInputFormatter release];
	[timeStampOutputFormatter release];
	[stockWall release];	
	[super dealloc];
}


@end